#pragma once

#include <iostream>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <cstdio>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <cassert>
#include <fcntl.h>
#include <sys/stat.h>//用于mkfifo函数
#include "Log.hpp"

using namespace std;//不推荐，有命名污染

#define PATH_NAME "/home/LX"

#define PROJ_ID 0x66
#define SHM_SIZE 4096 //共享内存的大小，最好是页（PAGE:4096)的整数倍
//若是大于1PAGE，则会开辟2PAGE空间，但是你只能用你申请的空间的大小。
//如SHM_SIZE若是4097，则会开辟2*4096，但你只能用其中的4097

#define FIFO_NAME "./fifo"

class Init
{
    public:
    Init()
    {
        cout<<"构造函数"<<endl;
     umask(0);//初始化掩码设置为0
     int n= mkfifo(FIFO_NAME,0666);
     
     Log("create fifo success",Notice)<<"FIFO_NAME:"<<FIFO_NAME<<endl;
    }
    ~Init()
    {
        unlink(FIFO_NAME);//unlink()函数功能即为删除文件。执行unlink()函数会删除所给参数指定的文件。
        Log("remove fifo success",Notice)<<"FIFO_NAME:"<<FIFO_NAME<<endl;
    
    }
};
// Init init;//对应的程序在加载的时候会自动构建全局变量,（创建时）该全局变量的类的构造函数会自动构建管道文件，（程序退出时）析构函数会自动删除管道文件
//该全局变量被两个进程加载到时，每个进程都会有自己的一个全局变量init,但两个init打开的是同一个管道文件，对同一个管道文件进行操作。区别于在头文件命名全局变量时的重定义。
//但是由于创建两次，有两次构造，会创建两次同一个fifo，会assert报错，所以不能让两个可执行程序都加载到这个全局变量，不能让他创建两次，我们只需用init的函数，不需要创建init，只需要有一个可执行程序创建init的即可。
//所以要放到其他可执行程序中去。


#define READ O_RDONLY
#define WRITE O_WRONLY
int OpenFIFO(std::string pathname,int flags)
{
    Log("打开管道文件",Debug)<<endl;
    int fd=open(pathname.c_str(),flags);//open返回文件的描述符，若打开不存在的文件则返回-1,若加上创建的命令，则返回创建的文件的fd
    assert(fd>=0);
    return fd;
}

void Wait(int fd)
{
    Log("等待写端写入中...",Debug)<<endl;
    uint32_t temp=0;
    ssize_t s=read(fd,&temp,sizeof(uint32_t));//读4个字节//从0中读 写到fd中
    assert(s == sizeof(uint32_t));
    (void)s;
}
void Signal(int fd)
{
    Log("写端已写入",Debug)<<endl;
    uint32_t temp=1;
    ssize_t s=write(fd,&temp,sizeof(uint32_t));//写4个字节//从fd中读 写到1中
    assert(s==sizeof(uint32_t));
    (void)s;
}

void CloseFifo(int fd)
{
    Log("关闭管道文件",Debug)<<endl;
    close(fd);
}